package com.jqkb.service;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jqkb.R;
import com.jqkb.TheApplication;
import com.jqkb.pages.BackwardDetailActivity;
import com.jqkb.pages.ForwardDetailActivity;
import com.jqkb.pages.LoginActivity;
import com.jqkb.pages.MainActivity;
import com.jqkb.service.util.SimpleApi;
import com.jqkb.utils.Constant;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;

import java.net.ConnectException;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

public class NewMessageService extends Service {
	
	public static final String TAG = "NewMessage";
	
	private NewMessageTask newMessageTask;
	
	private static int notificationCount = 100;
	
	private boolean serviceStop = false;
	
	private int foregroundId = 9999;
	
	@Nullable
	@Override
	public IBinder onBind(Intent intent) {
		return new MessageBinder(newMessageTask);
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "onStartCommand: 执行启动服务");
		if (TheApplication.getCurrentUser() != null) {
			if (newMessageTask == null || !newMessageTask.isRunning()) {
				Log.i(TAG, "新信息监听服务 开启 " + Thread.currentThread().getName());
				newMessageTask = new NewMessageTask();
				newMessageTask.start();
			} else {
				Log.i(TAG, "新信息监听服务 刷新 " + Thread.currentThread().getName());
				newMessageTask.refresh();
			}
			return START_STICKY;
		} else {
			Log.i(TAG, "onStartCommand: 未登录");
			if (newMessageTask != null) {
				newMessageTask.stopTask();
			}
			return START_NOT_STICKY;
		}
	}
	
	@Override
	public void onDestroy() {
		Log.i(TAG, "新信息监听服务 结束        停止：" + serviceStop);
//        Toast.makeText(this, "新信息监听服务 结束", Toast.LENGTH_SHORT).show();
		if (serviceStop) {
			if (newMessageTask != null) {
				newMessageTask.stopTask();
			}
		} else {
			Intent intent = new Intent(ScreenReceiver.class.getName());
			sendBroadcast(intent);
		}
	}
	
	/**
	 * 请求登录
	 *
	 * @param jsonNode
	 */
	private void startLogin(JsonNode jsonNode) {
		ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
		Intent          intent          = new Intent(this, LoginActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
	}
	
	/**
	 * 发现新信息
	 */
	private void onNewMessage(JsonNode jsonNode) {
		JsonNode           data     = jsonNode.path("data");
		Iterator<JsonNode> iterator = data.iterator();
		
		while (iterator.hasNext()) {
			JsonNode messages         = iterator.next();
			String   title            = messages.path("title").asText();
			String   type             = messages.path("type").asText();
			String   contentType      = messages.path("contentType").asText();
			Long     contentId        = messages.path("contentId").asLong();
			String   terminal         = messages.path("terminal").asText();
			String   sendUserName     = messages.path("sendUser").path("name").asText();
			String   sendUserUnitName = messages.path("sendUser").path("unit").path("name").asText();
			//todo 显示Notification
			
			Intent intent = null;
			String info   = "";
			
			if ("ActionBackward".equals(contentType)) {
				intent = new Intent(this, BackwardDetailActivity.class);
				intent.putExtra(Constant.BACKWARD_ID, contentId);
				info = "收到批复";
				
			} else {
				intent = new Intent(this, ForwardDetailActivity.class);
				intent.putExtra(Constant.FORWARD_ID, contentId);
				info = "收到信息";
			}
			
			
			intent.putExtra(Constant.NOTIFICATION_COUNT, ++notificationCount);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
			
			Uri           soundPath          = Uri.parse("android.resource://com.jqkb/raw/" + contentType.toLowerCase());
			PendingIntent notificationIntent = PendingIntent.getActivity(NewMessageService.this, notificationCount, intent, PendingIntent.FLAG_UPDATE_CURRENT);
			Notification notification = new Notification.Builder(NewMessageService.this)
					.setContentTitle(info)
					.setContentText(title)
					.setSmallIcon(R.mipmap.logo)
					.setSound(soundPath)
					.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.logo))
					.setContentIntent(notificationIntent)
					.setDefaults(Notification.DEFAULT_VIBRATE | Notification.FLAG_AUTO_CANCEL)
					.build();
			
			
			NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
			notificationManager.notify(notificationCount, notification);
			
		}
	}
	
	class NewMessageTask extends Thread {
		private boolean running;
		
		private int errorCount = 0;
		
		private Call<ResponseBody> currentCall;
		
		@Override
		public void run() {
			running = true;
			serviceStop = false;
			
			Thread notificationThread = new Thread() {
				@Override
				public void run() {
					while (running) {
						showAlive();
						try {
							TimeUnit.SECONDS.sleep(1);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			};
			notificationThread.start();
			
			Retrofit      retrofit      = SimpleApi.newInstance(3000, 1000 * 60 * 5, 1000 * 60 * 1);
			ActionService actionService = retrofit.create(ActionService.class);
			ObjectMapper  objectMapper  = new ObjectMapper();
			
			int previousCode = 0;
			log("开始监听信息");
			while (running) {
				try {
					currentCall = actionService.listenNewMessage();
					Response<ResponseBody> execute  = currentCall.execute();
					JsonNode               jsonNode = objectMapper.readTree(execute.body().charStream());
					int                    code     = jsonNode.path("code").asInt();
					
					if (code == 2000) {//有数据
						log("发现数据");
						errorCount = 0;
						onNewMessage(jsonNode);
					} else if (code == 2001) {//发现数据， 下次请求获得
						log("发现数据， 下次请求获得");
						errorCount = 0;
						continue;
					} else if (code == 1001) {//需要登录
						log("需要登录, 及时退出当前线程");
						serviceStop = true;
						startLogin(jsonNode);
						this.stopTask();
						stopSelf();
					} else if (code == 1003) {//没有新信息， 连接超时请重新连接
						log("没有新信息， 连接超时请重新连接");
						errorCount++;
						continue;
					} else if (code == 1008) {//一个Token同时只能监听一次, 请退出当前线程
						log("一个Token同时只能监听一次, 请退出当前线程");
						if (previousCode == code) {
							this.stopTask();
						}
					}
					
					previousCode = code;
				} catch (ConnectException e) {
					errorCount++;
					log("ConnectException:网络连接失败");
				} catch (Exception e) {
					errorCount++;
					e.printStackTrace();
				}
				
				/**
				 * 发生错误时候最多每一次多暂停1秒钟, 超过60次错误每60次增加1秒钟暂停
				 * 例子：错误60次暂停，1分钟
				 * 例子：错误65次暂停，1分钟
				 * 例子：错误120次暂停，1分钟2秒
				 * 例子：错误3600次暂停，1分钟60秒
				 * 例子：错误10800次暂停，1分钟120秒
				 */
				try {
					int second = Math.min(errorCount, Math.min(60 + errorCount / 60, 120));
					TimeUnit.SECONDS.sleep(second);
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
			running = false;
			log("结束监听信息");
		}
		
		public void stopTask() {
			this.running = false;
			if (currentCall != null) {
				currentCall.cancel();
			}
			if (this.getState() == State.RUNNABLE)
				this.interrupt();
		}
		
		public boolean isRunning() {
			return running;
		}
		
		public void refresh() {
			if (currentCall != null) {
				currentCall.cancel();
			}
		}
	}
	
	private void showAlive() {
//        boolean showAlive = TheApplication.getSharedPreferences().getBoolean("showAlive", false);
		
		PendingIntent contentIntent = PendingIntent.getActivity(
				this, 0, new Intent(this, MainActivity.class), 0);
		
		String format = String.format("%tF %1$tT", System.currentTimeMillis());
		Notification notification = new Notification.Builder(NewMessageService.this)
				.setContentTitle("JQKB正在运行")
				.setContentText(format)
				.setSmallIcon(R.mipmap.logo)
				.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.logo))
				.setDefaults(Notification.FLAG_AUTO_CANCEL)
				.setContentIntent(contentIntent)
				.build();
//            NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
//            notificationManager.notify(foregroundId, notification);
		
		
		startForeground(foregroundId, notification);
	}
	
	private void log(String text) {
		Log.i(TAG, String.format("[%s]:%s", Thread.currentThread().getName(), text));
	}
	
	public static class MessageBinder extends Binder {
		private NewMessageTask newMessageTask;
		
		public MessageBinder(NewMessageTask newMessageTask) {
			this.newMessageTask = newMessageTask;
		}
		
		public boolean isServiceAlive() {
			return newMessageTask.isRunning();
		}
	}
}
